package com.seh.contentcenter.service.Impl;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.seh.contentcenter.dto.CommentDTO;
import com.seh.contentcenter.dto.CommentsDTO;
import com.seh.contentcenter.dto.ReplyDTO;
import com.seh.contentcenter.dto.UserDTO;
import com.seh.contentcenter.entity.Comment;
import com.seh.contentcenter.feignclient.UserCenterFeignClient;
import com.seh.contentcenter.mapper.CommentMapper;
import com.seh.contentcenter.service.CommentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Slf4j
@Service
public class CommentServiceImpl implements CommentService {
    @Autowired
    private CommentMapper commentMapper;
    @Autowired
    private ReplyServiceImpl replyService;
    @Autowired
    private UserCenterFeignClient userCenterFeignClient;
    @Autowired
    private RedisTemplate<String, Object> objectRedisTemplate;


    //每页数据量
    private static int numSize = 4;

    //设置时间格式
    private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");

    /**
     * 查询一个帖子下，所有楼层的所有回复
     * 查询所有评论
     *
     * @return
     */
    @Cacheable(value = "comments", key = "#postId + '_' + #currentPage")
    @Override
    public CommentDTO getAllComments(Integer postId, Integer currentPage) {
        // 检查缓存中是否存在数据
        Boolean hasKey = objectRedisTemplate.opsForHash().hasKey("comments", postId + "_" + currentPage);
        if (hasKey) {
            // 从缓存中获取数据
            CommentDTO cachedCommentDTO = JSONObject.parseObject(objectRedisTemplate.opsForHash().get("comments", postId + "_" + currentPage).toString(), CommentDTO.class);

            return cachedCommentDTO;
        } else {
            Page<Comment> commentPage = new Page<>(currentPage, numSize);
            QueryWrapper<Comment> queryWrapper = new QueryWrapper<Comment>().orderByAsc("id");
            queryWrapper.eq("post_id", postId);
            Page<Comment> commentPage1 = commentMapper.selectPage(commentPage, queryWrapper);
            List<Comment> comments = commentPage1.getRecords();

            List<CommentsDTO> commentsDTOList = new ArrayList<>();
            for (Comment comment : comments) {
                CommentsDTO commentsDTO = new CommentsDTO();
                //将输入库插入到的数据存入commentsDTO中
                BeanUtils.copyProperties(comment, commentsDTO);
                List<ReplyDTO> repliesByCommentId = replyService.getRepliesByCommentId(comment.getFid(), 1);
                commentsDTO.setReplies(repliesByCommentId);

                commentsDTO.setCurrentPage(1);//当前页码
                commentsDTO.setTotalPages((int) ReplyServiceImpl.replySize);//总页数
                commentsDTO.setTotalDataSize(120);//数据总量
                commentsDTO.setPageSize(numSize);//每页数据量
                commentsDTO.setNextPage(2);//下一页页码
                commentsDTO.setPrefPage(0);//上一页页码
                commentsDTO.setUserPic(getUserPic(comment.getUserId()));

                commentsDTOList.add(commentsDTO);
            }
            CommentDTO commentDTO = new CommentDTO();
            commentDTO.setComments(commentsDTOList);
            commentDTO.setCurrentPage(currentPage);//当前页码
            commentDTO.setTotalPages((int) commentPage.getPages());//总页数
            commentDTO.setTotalDataSize(120);//数据总量
            commentDTO.setPageSize(numSize);//每页数据量
            commentDTO.setNextPage(currentPage + 1);//下一页页码
            commentDTO.setPrefPage(currentPage - 1);//上一页页码
            commentDTO.setPostId(postId);

            // 将查询结果存入缓存
            objectRedisTemplate.opsForHash().put("comments", postId + "_" + currentPage, JSONUtil.toJsonStr(commentDTO));

            return commentDTO;
        }
    }

    /**
     * 查询一个帖子下，一个楼层的所有回复
     * 查询某一楼评论
     *
     * @param id
     * @return
     */
    @Cacheable(value = "comment", key = "#id + '_' + #currentPage")
    @Override
    public CommentDTO getCommentById(Integer id, Integer currentPage) {
        // 检查缓存中是否存在数据
        Boolean hasKey = objectRedisTemplate.opsForHash().hasKey("comment", id + "_" + currentPage);
        if (hasKey) {
            // 从缓存中获取数据
            CommentDTO cachedCommentDTO = JSONObject.parseObject(objectRedisTemplate.opsForHash().get("comment", id + "_" + currentPage).toString(), CommentDTO.class);
            return cachedCommentDTO;
        } else {
            QueryWrapper<Comment> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("fid", id);
            Comment comment = commentMapper.selectOne(queryWrapper);
            CommentsDTO commentsDTO = new CommentsDTO();
            List<ReplyDTO> replies = replyService.getRepliesByCommentId(id, currentPage);
            commentsDTO.setReplies(replies);

            BeanUtils.copyProperties(comment, commentsDTO);
            List<CommentsDTO> commentsDTOList = new ArrayList<>();
            commentsDTO.setCurrentPage(currentPage);//当前页码
            commentsDTO.setTotalPages((int) ReplyServiceImpl.replySize);//总页数
            commentsDTO.setTotalDataSize(120);//数据总量
            commentsDTO.setPageSize(numSize);//每页数据量
            commentsDTO.setNextPage(currentPage + 1);//下一页页码
            commentsDTO.setPrefPage(currentPage - 1);//上一页页码

            commentsDTOList.add(commentsDTO);

            CommentDTO commentDTO = new CommentDTO();
            commentDTO.setComments(commentsDTOList);
            commentDTO.setCurrentPage(currentPage);
            commentDTO.setTotalPages((int) ReplyServiceImpl.replySize);
            commentDTO.setNextPage(currentPage + 1);

            // 将查询结果存入缓存
            objectRedisTemplate.opsForHash().put("comment", id + "_" + currentPage, JSONUtil.toJsonStr(commentDTO));

            return commentDTO;
        }
    }

    /**
     * 新增评论--回复帖子
     *
     * @param username
     * @param content
     * @return
     */
    @Override
    public String insertCommentAboutPost(Integer postId, String username, String content, Integer userId) {
        Date date = new Date();
        Comment comment = new Comment();
        comment.setFid((int) date.getTime());
        comment.setComment(content);//设置评论内容
        comment.setPosterName(username);//设置发布评论的用户名称
        comment.setDate(date);
        comment.setPostId(postId);
        comment.setUserId(userId);
        int insert = commentMapper.insert(comment);
        if (insert == 1) {
            // 删除对应的缓存条目
            objectRedisTemplate.delete("comments");
            return "添加成功";
        }
        return "添加失败";

    }

    /**
     * 获取回复帖子的数量
     * 根据帖子ID post_id 查询
     *
     * @param commentId
     * @return
     */
    @Override
    public Integer commentNums(Integer commentId) {
        QueryWrapper<Comment> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("post_id", commentId);
        Integer aLong = Math.toIntExact(commentMapper.selectCount(queryWrapper));
        return aLong;
    }

    /**
     * 通过帖子id查询一个帖子所有fid
     *
     * @param postId
     * @return
     */
    @Override
    public List<Integer> findAllFid(Integer postId) {
        QueryWrapper<Comment> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("post_id", postId);
        List<Comment> commentList = commentMapper.selectList(queryWrapper);
        List<Integer> list = new ArrayList<>();
        commentList.forEach(f -> {
            list.add(f.getFid());
        });
        return list;
    }

    /**
     * 获取用户头像地址
     *
     * @param userId
     * @return
     */
    @Cacheable(value = "userPic", key = "#userId")
    public String getUserPic(Integer userId) {
        UserDTO userDTO = userCenterFeignClient.findUserInfoById(userId);
        String pic = userDTO.getPic();
        return pic;
    }

}
